#include "afx.h"
#include "stdafx.h"
#include "afxwin.h"
#include "DeviceService.h"

#define CHECK_PRX_PERIOD	100

static char USB_BUFFER[8];
static int USB_BUFFER_COUNT;
static char READ_BUFFER[1024];
static char WRITE_BUFFER[1024];

static void initService(DeviceService *srv) {
	srv->readBuffer = new CBuffer(READ_BUFFER, sizeof(READ_BUFFER));
	srv->writeBuffer = new CBuffer(WRITE_BUFFER, sizeof(WRITE_BUFFER));

	srv->readBufferMutex = new CMutex();
	srv->writeBufferMutex = new CMutex();
}

DeviceService::DeviceService(UsbDevice *dev) {
	usbDevice = dev;
	initService(this);
}

DeviceService::DeviceService(void) {
	// usbDevice = new UsbDevice();
	usbDevice = NULL;
	initService(this);
}

DeviceService::~DeviceService() {
	if(usbDevice)
		delete(usbDevice);
	delete(readBuffer);
	delete(writeBuffer);
	delete(readBufferMutex);
	delete(writeBufferMutex);
}

void DeviceService::Start() {
	serviceStop = false;
	AfxBeginThread((AFX_THREADPROC)ServiceThread, this);
}

void DeviceService::Stop() {
	serviceStop = true;
}

void DeviceService::PostServiceMsg(enum DevMsg msg) {
	::PostMessage(AfxGetMainWnd()->m_hWnd, WM_USEV_MESSAGE, msg, 0);
}

int DeviceService::write(char *buffer, int len) {
	// write to the CBuffer cache
	return writeBuffer->write((const char *)buffer, len);
}

UINT DeviceService::ServiceThread(LPVOID *ptr) {
	DeviceService *service = (DeviceService  *)ptr;
	int nByte;
	int onlyOneTime = 1;
	int ret;
	static int stateCheckCount = 0;

	while (1) {
		// try to open USB device
			if(service->usbDevice == NULL)
			service->usbDevice = new UsbDevice();
		
		if(service->usbDevice->isDeviceOpen() == false) {
			// that means the PTX device is missing
			if(service->usbDevice->OpenUsbDevice() == -1) {
				service->PostServiceMsg(DEV_MSG_PTX_LOST);
				continue;
			} else {
				Sleep(100);
				service->PostServiceMsg(DEV_MSG_PTX_FOUND);
			}
		} else {
			if(onlyOneTime) {
				service->PostServiceMsg(DEV_MSG_PTX_FOUND);
				onlyOneTime = 0;
			}
		}

		// check the PRX device state every CHECK_PRX_PERIOD times
		//stateCheckCount = (stateCheckCount + 1) % CHECK_PRX_PERIOD;
		//if(stateCheckCount == 1) {
		//	ret = service->usbDevice->ctrl(PTX_RQ_GET_STATUS, 0, 0, USB_BUFFER, 1);
		//	// something goes wrong
		//	if(ret != 1) {
		//		// service->usbDevice->CloseUsbDevice();
		//		continue;
		//	}
		//	
		//	if(USB_BUFFER[0] & PTX_STATUS_MAXRT) {
		//		// that means the PRX device is missing
		//		service->PostServiceMsg(DEV_MSG_PRX_LOST);
		//	} else {
		//		service->PostServiceMsg(DEV_MSG_PRX_FOUND);
		//	}
		//	continue;
		//}
		
		
		// read from USB device
		memset(USB_BUFFER, 0xff, 8);
		nByte = service->usbDevice->read(USB_BUFFER, sizeof(USB_BUFFER));
		if(nByte > 0) {
			// service->readBufferMutex->Lock();
			service->readBuffer->write(USB_BUFFER, nByte);
			// service->readBufferMutex->Unlock();
			
			service->PostServiceMsg(DEV_MSG_DATA_RX);
		}

		// write to USB device
		// service->writeBufferMutex->Lock();
		nByte = service->writeBuffer->read(USB_BUFFER, sizeof(USB_BUFFER));
		// service->writeBufferMutex->Unlock();
		
		if(nByte) {
			service->usbDevice->write(USB_BUFFER, nByte);
		}

		if(service->serviceStop) {
			if(service->usbDevice)
				delete(service->usbDevice);
			service->usbDevice = NULL;
			break;
		}
	}
	return 0;
}



